unit datamodule;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, sqlite3conn, sqldb, FileUtil, LResources, Forms, Controls,
  Dialogs, Menus, ActnList, frmTreeEdit, db;

type

  { TDM }

  TDM = class(TDataModule)
    acAddParent: TAction;
    acAddChild: TAction;
    acDelNode: TAction;
    acAddNote: TAction;
    acRenameTree: TAction;
    acReReadMemo: TAction;
    acMemoClean: TAction;
    acFullExpand: TAction;
    acFullCollapse: TAction;
    acSeparator: TAction;
    acCopyTree: TAction;
    acAddCopyTree: TAction;
    ActionList: TActionList;
    ColorDialog1: TColorDialog;
    FindDialog1: TFindDialog;
    FontDialog1: TFontDialog;
    imgList16: TImageList;
    imgList32: TImageList;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    puFullExpand: TMenuItem;
    puFullCollapse: TMenuItem;
    puReReadMemo: TMenuItem;
    puRenameTree: TMenuItem;
    puAddNote: TMenuItem;
    puMemoClean: TMenuItem;
    puAddCopyTree: TMenuItem;
    puCopyTree: TMenuItem;
    MenuItem5: TMenuItem;
    puDelNode: TMenuItem;
    puAddParent: TMenuItem;
    puAddChild: TMenuItem;
    OpenDialog1: TOpenDialog;
    puMenuTree: TPopupMenu;
    ReplaceDialog1: TReplaceDialog;
    SaveDialog1: TSaveDialog;
    SQL_C: TSQLite3Connection;
    SQL_Q: TSQLQuery;
    SQL_T: TSQLTransaction;
    procedure acAddChildExecute(Sender: TObject);
    procedure acAddCopyTreeExecute(Sender: TObject);
    procedure acAddNoteExecute(Sender: TObject);
    procedure acAddParentExecute(Sender: TObject);
    procedure acCopyTreeExecute(Sender: TObject);
    procedure acDelNodeExecute(Sender: TObject);
    procedure acFullCollapseExecute(Sender: TObject);
    procedure acFullExpandExecute(Sender: TObject);
    procedure acMemoCleanExecute(Sender: TObject);
    procedure acRenameTreeExecute(Sender: TObject);
    procedure acReReadMemoExecute(Sender: TObject);
    procedure StepParent(ID: Integer);
  private
    { private declarations }
  public
    { public declarations }
  end; 

var
  DM: TDM;

implementation

uses main;
{ TDM }

procedure TDM.acAddParentExecute(Sender: TObject);
begin
  FormMain.TreeMain.Tag:=1;
  Application.CreateForm(TFormTreeEdit, FormTreeEdit);
  FormTreeEdit.ShowModal;
  FormTreeEdit.Free;
  FormMain.TreeMain.Items.Clear;
  FormMain.TreeExpand(nil);
  StepParent(-1);
end;

procedure TDM.acCopyTreeExecute(Sender: TObject);
begin
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree ='+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+';');
  SQL_Q.Open;
  DM.acCopyTree.Tag:=SQL_Q.FieldByName('IdTree').asInteger;
end;

procedure TDM.acDelNodeExecute(Sender: TObject);
var
   FieldParent: string;
   i, g, iID, cID: integer;
   arrID: array of integer;
begin
  SetLength(arrID, 1);
  g:=0;
  iID:=Integer(FormMain.TreeMain.Selected.Data);
  arrID[g]:=iID;
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree ='+IntToStr(iID)+';');
  SQL_Q.Open;
  cID:=SQL_Q.FieldByName('Parent').asInteger;
  while g < Length(arrID) do begin
    SQL_Q.Close;
    SQL_Q.SQL.Clear;
    SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE CCOUNT > 0 AND Parent ='+IntToStr(arrID[g])+';');
    SQL_Q.Open;
    for i:=1 to SQL_Q.RecordCount do begin
      SetLength(arrID, Length(arrID)+1);
      arrID[Length(arrID)-1]:=SQL_Q.FieldByName('IDTree').asInteger;
      SQL_Q.Next;
    end;
      g:=g+1;
  end;
  g:=0;
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add ('DELETE FROM BTree WHERE IDTree='+IntToStr(arrID[g])+';');
  SQL_Q.ExecSQL;
  while g < Length(arrID) do begin
    try
      SQL_Q.Close;
      SQL_Q.SQL.Clear;
      SQL_Q.SQL.Add ('DELETE FROM BTree WHERE Parent='+IntToStr(arrID[g])+';');
      SQL_Q.ExecSQL;
      g:=g+1;
    except
      ShowMessage('Ошибка при удалении записей БД.');
      SQL_T.Rollback;
    end;
  end;
  SQL_T.Commit;
  FormMain.TreeMain.Items.Clear;
  FormMain.TreeExpand(nil);
  StepParent(cID);
  FormMain.TreeMainChange(nil, nil);
end;

procedure TDM.acFullCollapseExecute(Sender: TObject);
begin
  Formmain.TreeMain.FullCollapse;
end;

procedure TDM.acFullExpandExecute(Sender: TObject);
begin
  Formmain.TreeMain.FullExpand;
end;

procedure TDM.acMemoCleanExecute(Sender: TObject);
begin
  FormMain.MemoMain.Lines.Clear;
end;

procedure TDM.acRenameTreeExecute(Sender: TObject);
var
  iID: integer;
begin
  iID:=Integer(FormMain.TreeMain.Selected.Data);
  FormMain.TreeMain.Tag:=2;
  Application.CreateForm(TFormTreeEdit, FormTreeEdit);
  FormTreeEdit.ShowModal;
  FormTreeEdit.Free;
  FormMain.TreeMain.Items.Clear;
  FormMain.TreeExpand(nil);
  StepParent(iID);
end;

procedure TDM.acReReadMemoExecute(Sender: TObject);
var
  Stream: TStream;
begin
  DM.SQL_Q.Close;
  DM.SQL_Q.SQL.Clear;
  DM.SQL_Q.SQL.Add ('SELECT * FROM Notes WHERE TreeID ='+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+';');
  DM.SQL_Q.Open;
  if DM.SQL_Q.FieldByName('TreeID').AsInteger = Integer(FormMain.TreeMain.Selected.Data) then begin
    Stream:=DM.SQL_Q.CreateBlobStream(DM.SQL_Q.FieldByName('Note'), bmRead);
    try
      FormMain.MemoMain.Lines.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;
  end else begin
    FormMain.MemoMain.Lines.Clear;
  end;
  FormMain.MemoMain.Modified:=FALSE;
end;

procedure TDM.acAddChildExecute(Sender: TObject);
begin
  FormMain.TreeMain.Tag:=0;
  Application.CreateForm(TFormTreeEdit, FormTreeEdit);
  FormTreeEdit.ShowModal;
  FormTreeEdit.Free;
  FormMain.TreeMain.Items.Clear;
  FormMain.TreeExpand(nil);
  StepParent(-1);
end;

procedure TDM.acAddCopyTreeExecute(Sender: TObject);
var
  FieldParent: string;
begin
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree ='+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+';');
  SQL_Q.Open;
  FieldParent:=SQL_Q.FieldByName('Parent').AsString;
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add('UPDATE BTree SET Parent='+FieldParent+' WHERE IDTree='+IntToStr(DM.acCopyTree.Tag)+';');
  SQL_Q.ExecSQL;
  SQL_T.Commit;
  FormMain.TreeMain.Items.Clear;
  FormMain.TreeExpand(nil);
  StepParent(DM.acCopyTree.Tag);
end;

procedure TDM.acAddNoteExecute(Sender: TObject);
begin
  SQL_Q.Close;
  SQL_Q.SQL.Clear;
  SQL_Q.SQL.Add('SELECT * FROM Notes WHERE TreeID= '+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+';');
  SQL_Q.Open;
  if SQL_Q.RecordCount = 0 then begin
    SQL_Q.Close;
    SQL_Q.SQL.Clear;
    SQL_Q.SQL.Add('INSERT INTO Notes VALUES (NULL,'+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+', '''+FormMain.MemoMain.Lines.Text+''');');
    SQL_Q.ExecSQL;
    SQL_T.Commit;
  end else begin
    SQL_Q.Close;
    SQL_Q.SQL.Clear;
    SQL_Q.SQL.Add('UPDATE Notes SET Note='''+FormMain.MemoMain.Lines.Text+''' WHERE TreeID='+IntToStr(Integer(FormMain.TreeMain.Selected.Data))+';');
    SQL_Q.ExecSQL;
    SQL_T.Commit;
  end;
  FormMain.MemoMain.Modified:=FALSE;
end;

procedure TDM.StepParent(ID: Integer);
var
   FieldParent: string;
   i, g, iID, FieldCCount: integer;
   arrID: array of integer;
begin
  iID:=1;
  if ID < 0 then begin
    SQL_Q.Close;
    SQL_Q.SQL.Clear;
    SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree=(SELECT MAX(IDTree) FROM BTree);');
    SQL_Q.Open;
  end
  else begin
    SQL_Q.Close;
    SQL_Q.SQL.Clear;
    SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree='+IntToStr(ID)+';');
    SQL_Q.Open;
  end;
  FieldCCount:=SQL_Q.FieldByName('CCount').asInteger;
  SetLength(arrID,iID);
  arrID[iID-1]:=SQL_Q.FieldByName('IDTree').asInteger;
  while SQL_Q.FieldByName('Parent').asInteger <> 0 do begin
      FieldParent:=IntToStr(SQL_Q.FieldByName('Parent').asInteger);
      SQL_Q.Close;
      SQL_Q.SQL.Clear;
      SQL_Q.SQL.Add ('SELECT * FROM BTree WHERE IDTree='+FieldParent+';');
      SQL_Q.Open;
      iID:=iID+1;
      SetLength(arrID,iID);
      arrID[iID-1]:=SQL_Q.FieldByName('IDTree').asInteger;
  end;
  FormMain.TreeMain.Items.BeginUpdate;
  if ID <> 0  then begin
    for g:=0 to Length(arrID)-1 do begin
      for i:=0 to FormMain.TreeMain.Items.Count-1 do begin
        if Integer(FormMain.TreeMain.Items.Item[i].Data) = arrID[Length(arrID)-1-g]
        then begin
          FormMain.TreeMain.Items.Item[i].Expanded:=TRUE;
          FormMain.TreeMain.Items.Item[i].Selected:=TRUE;
          FormMain.TreeMain.Repaint;
        end;
      end;
    end;
  end else begin
    FormMain.TreeMain.Items.Item[0].Selected:=TRUE;
  end;
  FormMain.TreeMain.Items.EndUpdate;
end;
initialization
  {$I datamodule.lrs}

end.

